import React, { useEffect, useState } from "react";
import "./index.scss";
import {
    Breadcrumb,
    Card,
    Input,
    Row,
    Col,
    Select,
    Button,
    Radio,
    Space,
    message,
} from "antd";

import { MergeRouteComponentProps } from "../../../../router/types";

import {
    addUserItem,
    fetchRoleList,
    fetchUserList,
    updateUserItem,
    UserFormInterface,
    addRoleItem,
    RoleFormInterface,
    AclFormInterface,
    addAclItem,
    fetchAclList,
    RoleAclFormInterface,
    addRoleAclItem,
} from "../../../../http/user";

interface IProps extends MergeRouteComponentProps {}

/**
 * 初始化表单数据：用户
 */
const initialUserForm: UserFormInterface = {
    uid: undefined,
    username: "",
    password: "",
    nickname: "",
    rid: undefined,
};

/**
 * 初始化表单数据：角色
 */
const initialRoleForm: RoleFormInterface = {
    name: "",
};

/**
 * 初始化表单数据：权限
 */
const initialAclForm: AclFormInterface = {
    name: "",
    path: "",
    method: undefined,
    type: 2,
};

/**
 * 初始化表单数据：角色权限
 */
const initialRoleAclForm: RoleAclFormInterface = {
    rid: undefined,
    aid: undefined,
};

const UserAdd: React.FC<IProps> = () => {
    /**
     * 组件状态：操作按钮
     */
    const [operator, setOperator] = useState({
        user: "add",
        role: "add",
        acl: "add",
        roleAcl: "addUi",
    });

    /**
     * 组件状态：列表数据
     */
    const [list, setList] = useState<{
        role: Array<{ id: string; name: string }>;
        user: Array<{
            id: string;
            username: string;
            nickname: string;
        }>;
        acl: Array<{
            id: string;
            name: string;
        }>;
    }>({ role: [], user: [], acl: [] });

    /**
     * 用户表单
     */
    const [userForm, setUserForm] = useState<UserFormInterface>({
        ...initialUserForm,
    });

    /**
     * 角色表单
     */
    const [roleForm, setRoleForm] = useState<RoleFormInterface>({
        ...initialRoleForm,
    });

    /**
     * 权限表单
     */
    const [aclForm, setAclForm] = useState<AclFormInterface>({
        ...initialAclForm,
    });

    /**
     * 角色权限表单
     */
    const [roleAclForm, setRoleAclForm] = useState<RoleAclFormInterface>({
        ...initialRoleAclForm,
    });

    /**
     * 监听角色权限切换，重新获取权限列表
     * 需要注意 hooks 顺序，放在初始化后，会产生覆盖，导致「用户列表」和「角色列表」为空
     * 因为这两个 hooks 都调用了 setList()
     */
    useEffect(() => {
        getAclList(operator.roleAcl === "addUi" ? 1 : 2);
        setRoleAclForm({ ...initialRoleAclForm });
    }, [operator.roleAcl]);

    /**
     * 副作用：发请求
     */
    useEffect(() => {
        (async () => {
            const resArr = await Promise.all([
                fetchUserList(),
                fetchRoleList(),
                fetchAclList(1),
            ]);
            setList({
                user: resArr[0].data.data,
                role: resArr[1].data.data,
                acl: resArr[2].data.data,
            });
        })();
    }, []);

    /**
     * 请求数据：用户列表
     */
    const getUserList = async () => {
        const res = await fetchUserList();
        res.data.data && setList({ ...list, user: res.data.data });
    };

    /**
     * 请求数据：角色列表
     */
    const getRoleList = async () => {
        const res = await fetchRoleList();
        res.data.data && setList({ ...list, role: res.data.data });
    };

    /**
     * 请求数据：权限列表
     * @param type 权限类型
     */
    const getAclList = async (type: number) => {
        const res = await fetchAclList(type);
        res.data.data && setList({ ...list, acl: res.data.data });
    };

    /**
     * 确定按钮：用户
     */
    const onUserConfirmClicked = async () => {
        // 添加用户
        if (operator.user === "add") {
            const res = await addUserItem(userForm);
            if (res.data.code !== 201) {
                message.error(res.data.message);
                return;
            }
            // 提示添加成功
            message.success("添加成功");
            // 重置表单
            setUserForm({ ...initialUserForm });
            // 重新初始化一下列表数据，因为包含了用户信息
            getUserList();
            return;
        }

        // 修改用户
        if (operator.user === "update") {
            const res = await updateUserItem(userForm);
            if (res.data.code !== 200) {
                message.error(res.data.message);
                return;
            }
            // 提示添加成功
            message.success("添加成功");
            // 重置表单
            setUserForm({ ...initialUserForm });
            // 重新初始化列表数据
            getUserList();
            return;
        }
    };

    /**
     * 确定按钮：角色
     */
    const onRoleConfirmClicked = async () => {
        const res = await addRoleItem(roleForm);
        if (res.data.code !== 201) {
            message.error(res.data.message);
            return;
        }
        // 提示添加成功
        message.success("添加成功");
        // 重置表单
        setRoleForm({ ...initialRoleForm });
        // 重新初始化列表数据
        getRoleList();
        return;
    };

    /**
     * 确定按钮：权限
     */
    const onAclClicked = async () => {
        const res = await addAclItem(aclForm);
        if (res.data.code !== 201) {
            message.error(res.data.message);
            return;
        }
        // 提示添加成功
        message.success("添加成功");
        // 重置表单
        setAclForm({ ...initialAclForm });
        // 重新初始化列表数据
        getAclList(operator.roleAcl === "addUi" ? 1 : 2);
        return;
    };

    /**
     * 确定按钮：角色权限
     */
    const onRoleAclClicked = async () => {
        const res = await addRoleAclItem(roleAclForm);
        if (res.data.code !== 201) {
            message.error(res.data.message);
            return;
        }
        // 提示添加成功
        message.success("添加成功");
        // 重置表单
        setRoleAclForm({ ...initialRoleAclForm });
    };

    return (
        <div className="user-add">
            {/* 面包屑导航 */}
            <Breadcrumb>
                <Breadcrumb.Item>
                    <a href="">首页</a>
                </Breadcrumb.Item>

                <Breadcrumb.Item>
                    <a href="">用户管理</a>
                </Breadcrumb.Item>

                <Breadcrumb.Item>
                    <a href="">添加用户</a>
                </Breadcrumb.Item>
            </Breadcrumb>

            {/* 操作面板 */}
            <Row gutter={[16, 16]}>
                {/* 第一个 Card */}
                <Col span="8">
                    <Card title="用户管理">
                        <Space
                            direction="vertical"
                            size="large"
                            className="block"
                        >
                            <Radio.Group
                                className="block"
                                style={{ textAlign: "center" }}
                                value={operator.user}
                                onChange={(e) =>
                                    setOperator({
                                        ...operator,
                                        user: e.target.value,
                                    })
                                }
                            >
                                <Radio.Button
                                    value="add"
                                    style={{ width: "50%" }}
                                >
                                    添加用户
                                </Radio.Button>

                                <Radio.Button
                                    value="update"
                                    style={{ width: "50%" }}
                                >
                                    更新用户
                                </Radio.Button>
                            </Radio.Group>

                            {operator.user === "update" && (
                                <Select
                                    className="block"
                                    placeholder="请选择用户"
                                    value={userForm.uid}
                                    onChange={(e: string) =>
                                        setUserForm({ ...userForm, uid: e })
                                    }
                                >
                                    {list.user.map((item) => (
                                        <Select.Option
                                            key={item.id}
                                            value={item.id}
                                        >
                                            {`${item.nickname} (${item.username})`}
                                        </Select.Option>
                                    ))}
                                </Select>
                            )}

                            <Input
                                placeholder="请输入用户名"
                                value={userForm.username}
                                onChange={(e) =>
                                    setUserForm({
                                        ...userForm,
                                        username: e.target.value,
                                    })
                                }
                            />

                            <Input
                                placeholder="请输入密码"
                                value={userForm.password}
                                onChange={(e) =>
                                    setUserForm({
                                        ...userForm,
                                        password: e.target.value,
                                    })
                                }
                            />

                            <Input
                                placeholder="请输入姓名或昵称"
                                value={userForm.nickname}
                                onChange={(e) =>
                                    setUserForm({
                                        ...userForm,
                                        nickname: e.target.value,
                                    })
                                }
                            />

                            <Select
                                className="block"
                                placeholder="请选择角色id"
                                value={userForm.rid}
                                onChange={(e: string) =>
                                    setUserForm({ ...userForm, rid: e })
                                }
                            >
                                {list.role.map((item) => (
                                    <Select.Option
                                        key={item.id}
                                        value={item.id}
                                    >
                                        {item.name}
                                    </Select.Option>
                                ))}
                            </Select>

                            <Button
                                block
                                type="primary"
                                onClick={onUserConfirmClicked}
                            >
                                确定
                            </Button>
                        </Space>
                    </Card>
                </Col>

                {/* 第二个 Card */}
                <Col span="8" className="block">
                    <Card title="角色管理">
                        <Space
                            direction="vertical"
                            size="large"
                            className="block"
                        >
                            <Radio.Group
                                disabled
                                className="block"
                                value={operator.role}
                                onChange={(e) =>
                                    setOperator({
                                        ...operator,
                                        user: e.target.value,
                                    })
                                }
                            >
                                <Radio.Button value="add">
                                    添加角色
                                </Radio.Button>
                            </Radio.Group>

                            <Input
                                value={roleForm.name}
                                placeholder="请输入角色名称"
                                onChange={(e) =>
                                    setRoleForm({
                                        ...roleForm,
                                        name: e.target.value,
                                    })
                                }
                            />

                            <Button
                                type="primary"
                                block
                                onClick={onRoleConfirmClicked}
                            >
                                确定
                            </Button>
                        </Space>
                    </Card>
                </Col>

                {/* 第三个 Card */}
                <Col span="8">
                    <Card title="权限管理">
                        <Space
                            direction="vertical"
                            size="large"
                            className="block"
                        >
                            <Radio.Group
                                value={operator.acl}
                                onChange={(e) =>
                                    setOperator({
                                        ...operator,
                                        acl: e.target.value,
                                    })
                                }
                            >
                                <Radio.Button value="add">
                                    添加权限
                                </Radio.Button>
                            </Radio.Group>

                            <Input
                                value={aclForm.name}
                                placeholder={`请输入${
                                    aclForm.type === 2 ? " API 接口" : "视图"
                                }权限名称`}
                                onChange={(e) =>
                                    setAclForm({
                                        ...aclForm,
                                        name: e.target.value,
                                    })
                                }
                            />

                            {aclForm.type === 2 && (
                                <>
                                    <Input
                                        value={aclForm.path}
                                        placeholder="请输入 API 接口的请求路径"
                                        onChange={(e) =>
                                            setAclForm({
                                                ...aclForm,
                                                path: e.target.value,
                                            })
                                        }
                                    />

                                    <Select
                                        className="block"
                                        value={aclForm.method}
                                        placeholder="请选择 API 接口的请求方式"
                                        onChange={(e) =>
                                            setAclForm({
                                                ...aclForm,
                                                method: e,
                                            })
                                        }
                                    >
                                        <Select.Option value="GET">
                                            GET 请求（查询）
                                        </Select.Option>

                                        <Select.Option value="POST">
                                            POST 请求（添加）
                                        </Select.Option>

                                        <Select.Option value="PUT">
                                            PUT 请求（修改）
                                        </Select.Option>

                                        <Select.Option value="DELETE">
                                            DELETE 请求（删除）
                                        </Select.Option>
                                    </Select>
                                </>
                            )}

                            <Radio.Group
                                value={aclForm.type}
                                onChange={(e) =>
                                    setAclForm({
                                        ...initialAclForm,
                                        type: e.target.value,
                                    })
                                }
                            >
                                <Radio value={2}>接口权限</Radio>
                                <Radio value={1}>视图权限</Radio>
                            </Radio.Group>

                            <Button type="primary" block onClick={onAclClicked}>
                                确定
                            </Button>
                        </Space>
                    </Card>
                </Col>
            </Row>

            <Row gutter={[16, 16]}>
                {/* 第四个 Card */}
                <Col span="8">
                    <Card title="角色权限">
                        <Space
                            className="block"
                            direction="vertical"
                            size="large"
                        >
                            <Radio.Group
                                style={{ textAlign: "center" }}
                                className="block"
                                value={operator.roleAcl}
                                onChange={(e) =>
                                    setOperator({
                                        ...operator,
                                        roleAcl: e.target.value,
                                    })
                                }
                            >
                                <Radio.Button
                                    value="addUi"
                                    style={{ width: "50%" }}
                                >
                                    给角色添加视图权限
                                </Radio.Button>

                                <Radio.Button
                                    value="addApi"
                                    style={{ width: "50%" }}
                                >
                                    给角色添加接口权限
                                </Radio.Button>
                            </Radio.Group>

                            <Select
                                className="block"
                                placeholder="请选择角色id"
                                value={roleAclForm.rid}
                                onChange={(val: string) =>
                                    setRoleAclForm({
                                        ...roleAclForm,
                                        rid: val,
                                    })
                                }
                            >
                                {list.role.map((item) => (
                                    <Select.Option
                                        key={item.id}
                                        value={item.id}
                                    >
                                        {item.name}
                                    </Select.Option>
                                ))}
                            </Select>

                            <Select
                                className="block"
                                placeholder={`请选择${
                                    operator.roleAcl === "addUi"
                                        ? "视图"
                                        : "接口"
                                }权限id`}
                                value={roleAclForm.aid}
                                onChange={(val: string) =>
                                    setRoleAclForm({
                                        ...roleAclForm,
                                        aid: val,
                                    })
                                }
                            >
                                {list.acl.map((item) => (
                                    <Select.Option
                                        key={item.id}
                                        value={item.id}
                                    >
                                        {item.name}
                                    </Select.Option>
                                ))}
                            </Select>

                            <Button type="primary" onClick={onRoleAclClicked}>
                                确定
                            </Button>
                        </Space>
                    </Card>
                </Col>
            </Row>
        </div>
    );
};

export default UserAdd;
